package JwtUtil

import (
	"QingDai-Gin/api/models"
	"QingDai-Gin/config"
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt"
	"strings"
	"time"
)

type UserClaims struct {
	models.User
	jwt.StandardClaims
}

func CreateJWT(id string, ttlMillis time.Duration, user models.User) (string, error) {
	// 定义token的过期时间
	userClaims := UserClaims{
		user,
		jwt.StandardClaims{
			Id:        id,
			ExpiresAt: time.Now().Add(ttlMillis * time.Second).Unix(), // 过期时间
			Issuer:    config.GetConfig().Jwt.Issue,                   // 签发人
		},
	}
	// 使用 JWT 签名算法生成token
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, userClaims)

	// 将token进行加盐加密
	// 注意：该方法参数虽然是interface{}，但是必须传入[]byte类型的参数
	tokenString, err := token.SignedString([]byte(config.GetConfig().Jwt.SecretKey))
	if err != nil {
		return "", err
	}
	return tokenString, nil
}

func ParseJWT(jwtString string) (*UserClaims, error) {
	token, err := jwt.ParseWithClaims(jwtString, &UserClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(config.GetConfig().Jwt.SecretKey), nil
	})
	if err != nil {
		//
		return nil, errors.New("令牌非法或过期")
	}
	if claims, ok := token.Claims.(*UserClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("invalid token")
}

func GetUserIdByContext(context *gin.Context) (int, error) {
	jwtString := context.GetHeader("Authorization")
	if jwtString == "" {
		return 0, errors.New("请登录后操作")
	}
	newStr := strings.Replace(jwtString, "bearer ", "", -1)
	if newStr == "" {
		return 0, errors.New("空令牌")
	}
	userClaims, err := ParseJWT(jwtString)
	if err != nil {
		return 0, err
	}
	return userClaims.ID, nil
}
